﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace SqlShareAPI
{
    class SSSqlConnection
    {

        /// <summary>
        ///  Connection to SQL Azure
        /// </summary>

        private string _metaConnectionString;
        private string _userContentConnectionString;
        private string _adminContentConnectionString;

        private SqlConnection _metaConnection;
        private SqlConnection _adminContentConnection;
        private SqlConnection _userContentConnection;

        private bool _isContentStringReady;
        private bool _isAdmin;

        public SSSqlConnection(string metaConnectionString, string adminContentConnectionString)
        {
            _metaConnectionString = metaConnectionString;
            _adminContentConnectionString = adminContentConnectionString;

            // this is set when 
            _isContentStringReady = false;

            //_sqlConnectionStrings["meta"] = "Server=tcp:u7t1o5e5s7.database.windows.net;User ID=sciflex;Password=eScience4All!;Trusted_Connection=False;Database = metaDB;";
        }

        /// <summary>
        /// Current password
        /// </summary>
        internal const string GlobalContentPassword = "eScience4All!";

        /// <summary>
        /// Content database connection. If the session has not been set this will throw an Exception 
        /// </summary>
        public SqlConnection UserContentConnection
        {
            get
            {
                if (!_isContentStringReady)
                {
                    throw new Exception("Invalid call to content connection without creating a UserSession first");
                }


                if (_userContentConnection == null)
                {
                    _userContentConnection = NewConnection(_userContentConnectionString);
                }
                return _userContentConnection;
            }
        }

        /// <summary>
        /// Admin connection, used to generate new users
        /// </summary>
        public SqlConnection AdminContentConnection
        {
            get
            {
                if (!_isAdmin)
                {
                    throw new Exception("Invalid call to admin content connection user admin was not established");
                }

                if (_adminContentConnection == null)
                {
                    _adminContentConnection = NewConnection(_adminContentConnectionString);
                }
                return _adminContentConnection;
            }
        }

        /// <summary>
        /// The meta connection that has Meta information
        /// </summary>
        public SqlConnection MetaConnection
        {
            get
            {
                if (_metaConnection == null)
                {
                    _metaConnection = NewConnection(_metaConnectionString);
                }
                return _metaConnection;
            }
        }        

        /// <summary>
        /// Set the session for this collection of databse connections
        /// </summary>
        /// <param name="session"></param>
        internal void SetUserSession(UserSession session)
        {
            string[] split = _adminContentConnectionString.Split(new char[] { ';' });

            string resultStr = "";
            // filter out the old USER ID
            foreach (string s in split)
            {
                if (s.ToLower().Contains("user id") || s.ToLower().Contains("password"))
                {
                    continue;
                }                
                resultStr += s + ";";
            }
            resultStr += "User ID=" + "meta_" + session.UserName + ";Password=" + GlobalContentPassword;
            _userContentConnectionString = resultStr;

            _isAdmin = session.IsAdmin;
            _isContentStringReady = true;
        }

        /// <summary>
        /// Close all database connections. 
        /// </summary>
        public void CloseAll()
        {

            if (_adminContentConnection != null)
            {
                _adminContentConnection.Close();
            }

            if (_userContentConnection != null)
            {
                _userContentConnection.Close();
            }

            if (_metaConnection != null)
            {
                _metaConnection.Close();
            }

        }

        /// <summary>
        /// Lazy initialization for SQL connection 
        /// </summary>
        private SqlConnection NewConnection(String connString)
        {
            // This example needs the 
            // System.Data.SqlClient library
            //string ConnectionString = "Server=tcp:u7t1o5e5s7.database.windows.net;Database=AzureTest;User ID=sciflex;Password=eScience4All!;Trusted_Connection=False;";
            //string ConnectionString = @"Server=(local)\SQLExpress;Database=COG;Trusted_Connection=True;";

            SqlConnection conn = new SqlConnection();

            try
            {
                conn.ConnectionString = connString;
                conn.Open();

                // You can get the server version 
                // SQLConnection.ServerVersion
            }
            catch (Exception Ex)
            {
                // Try to close the connection
                if (conn != null)
                    conn.Dispose();

                // Create a (useful) error message
                string ErrorMessage = "A error occurred while trying to connect to the server.";
                ErrorMessage += Environment.NewLine;
                ErrorMessage += Environment.NewLine;
                ErrorMessage += Ex.Message;

                // Show error message (this = the parent Form object)
                //MessageBox.Show(this, ErrorMessage, "Connection error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Console.WriteLine("Connection Error: \n\r" + ErrorMessage);

                // Stop here
                return null;
            }
            return conn;
        }
    }
}
